package org.potomak.patientmanager.persistence;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Date;
import java.util.List;
import java.util.ListIterator;
import java.util.Properties;

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.Query;
import javax.jdo.Transaction;

import org.potomak.patientmanager.beans.model.CheckUpBean;
import org.potomak.patientmanager.beans.model.PatientBean;
import org.potomak.patientmanager.beans.model.SimpleNoteBean;
import org.potomak.patientmanager.beans.model.ImportantNoteBean;
import org.potomak.patientmanager.beans.model.SuggestionNoteBean;

public class JPoxJDO {

	private static final String JPOX_CONFIG = "jpox.properties";
	private static Properties prop;
	private static String password;
	private boolean isInitialized = false;
	private PersistenceManager pm;

	public JPoxJDO(String password) {
		this.password = password;
		
		if (isInitialized) {
			return;
		} else {
			initialize();
		}
	}

	private void initialize() {
		System.out.println("JpoxJDO, initialize called");
		getDatasourceProps();
		prop.setProperty("javax.jdo.option.ConnectionURL",prop.getProperty("javax.jdo.option.ConnectionURL")+password);
		pm = createPersistenceManager();
		isInitialized = true;
		return;
	}
        
        public PersistenceManager getPersistenceManager() {
            return pm;
        }

	// load all of the various JPOX properties from a properties file

	private void getDatasourceProps() {
		InputStream is = this.getClass().getResourceAsStream(JPOX_CONFIG);

		prop = new Properties();
		try {
			prop.load(is);
		} catch (IOException exception) {
			throw new RuntimeException("jpox.properties not found.",exception);
		}
	}

	// create the PersistenceManager using the JDO Helper class
	// the persistencemanage is used for all JPOX transactions

	private static PersistenceManager createPersistenceManager() {

		PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(prop);

		return pmf.getPersistenceManager();

	}

	// close the persistence manager.

	public void shutdown() {
		if (pm != null) {
			pm.close();
		}

	}

	// If the username is in the APP.PATIENT table retrieve
	// the database row, which in JPOX is the class PatientBean

	public PatientBean getPatient(String patientName) {

		PatientBean patientBean;

		Transaction txn = pm.currentTransaction();
		try {
			txn.begin();
			// this represents the query:
			// select username, password from APP.USERS where username = ?
			Query query = pm.newQuery(PatientBean.class, "patientName == name");
			query.declareParameters("String patientName");
			query.setUnique(true);
			patientBean = (PatientBean)query.execute(patientName.trim());
			pm.retrieve(patientBean);
			if (patientBean == null) {
				patientBean = new PatientBean();
			}
			txn.commit();
		} finally {
			if (txn.isActive()) {
				txn.rollback();
			}
		}
		return patientBean;
	}

	// Insert a row into the APP.PATIENT table by first creating a
	// PatientBean, then using JPOX to persist the PatientBean to Derby.

	public boolean insertPatient(String name, Date birthDay, String gender, Double height, Double weight, Date date) {

		boolean success = false;
                
		PatientBean patientBean = new PatientBean(name.trim(),birthDay,gender.trim(),height,weight,date,new HashSet(), new HashSet(), new HashSet(), new HashSet(),new HashSet());
                patientBean.getSimpleNotes().add(new SimpleNoteBean());
                patientBean.getImportantNotes().add(new ImportantNoteBean());
                patientBean.getSuggestionNotes().add(new SuggestionNoteBean());

		Transaction txn = pm.currentTransaction();
		try {
			txn.begin();
			// I have to have this, otherwise it is not persistent
			pm.makePersistent(patientBean);

			txn.commit();
			success = true;
		} finally {
			if (txn.isActive()) {
				txn.rollback();
				success = false;
			}
		}

		return success;
	}

        /*
	// Insert a row into the APP.NOTE table by first creating a
	// NoteBean, then using JPOX to persist the NoteBean to Derby.

	public int insertNote(NoteBean note) {

		int success = 0;

		Transaction txn = pm.currentTransaction();
		try {
			txn.begin();
			// I have to have this, otherwise it is not persistent
			pm.makePersistent(note);

			txn.commit();
			success = 1;
		} finally {
			if (txn.isActive()) {
				txn.rollback();
				success = 0;
			}
		}

		return success;
	}
        */
        
        public boolean insertCheckUp(PatientBean patient, Double weight, Date date) {
            boolean success = false;

		Transaction txn = pm.currentTransaction();
		try {
			txn.begin();
                        CheckUpBean checkUp = new CheckUpBean(patient,weight,date);
			// I have to have this, otherwise it is not persistent
			pm.makePersistent(checkUp);

			txn.commit();
			success = true;
		} finally {
			if (txn.isActive()) {
				txn.rollback();
				success = false;
			}
		}

		return success;
        }
        
        public PatientBean[] patientList() {

		PatientBean[] patientBean;

		Transaction txn = pm.currentTransaction();
		try {

			txn.begin();

			Query query = pm.newQuery(PatientBean.class);
			query.setClass(PatientBean.class);
			List list = (List) query.execute();

			ListIterator iter = list.listIterator();

			if (list.size() > 0) {
				patientBean = new PatientBean[list.size()];
			} else {
				patientBean = new PatientBean[0];
			}
			int i = 0;

			while (iter.hasNext()) {
				patientBean[i++] = (PatientBean)iter.next();
			}

			txn.commit();
		} finally {
			if (txn.isActive()) {
				txn.rollback();
			}

		}

		return patientBean;
	}
	
}
